package com.openlogic.common.logic.run;

import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

import org.apache.commons.text.StringEscapeUtils;
import org.noear.solon.annotation.Component;
import org.noear.solon.core.event.AppBeanLoadEndEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.openlogic.common.core.utils.DateUtils;
import com.openlogic.common.logic.constants.RuleConstants;
import com.openlogic.common.logic.node.enums.NodeExecEnums;
import com.openlogic.common.logic.node.factory.NodeExecFactory;
import com.openlogic.common.logic.utils.NumericRegxUtils;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

/**
 * @ClassName: ExecMatrixNodeHandler
 * @Description: 矩阵（函数）节点运行执行器
 * @author weiyongpeng
 * @date 2024年7月17日 上午9:12:36
 */
@Component
public class ExecMatrixNodeHandler extends ExecRuleHandler {

	private static final Logger logger = LoggerFactory.getLogger(ExecMatrixNodeHandler.class);

	@Override
	public JSONObject typeRun(JSONArray resultArray1, JSONArray nodeArray, JSONArray lineArray, JSONObject inputjson,
			JSONArray areaArray, String areaFirst, String ruleId, StringBuffer reason, Map<String, Object> map) {
		JSONObject reJson = new JSONObject();
		logger.info("MartixNode Begin Run Starting...");
		// 默认节点解析后的数据
		logger.info("typeRun=====" + resultArray1.toString());
		reJson = recRunForNode(resultArray1, nodeArray, lineArray, inputjson, areaArray, areaFirst, ruleId, reason,
				map);
		return reJson;
	}

	/**
	 * 描述：迭代节点执行
	 * @Title: recRunForDefault
	 * @param resultArray1
	 * @param nodeArray
	 * @param lineArray
	 * @param inputjson
	 * @param areaArray
	 * @param areaFirst
	 * @param ruleId
	 * @param reason
	 * @param map
	 * @return
	 * @author weiyongpeng
	 * @date 2024年7月17日 上午10:29:23
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	protected JSONObject recRunForNode(JSONArray resultArray1, JSONArray nodeArray, JSONArray lineArray,
			JSONObject inputjson, JSONArray areaArray, String areaFirst, String ruleId, StringBuffer reason,
			Map<String, Object> map) {
		Map<Object, Object> inParam = new HashMap<>();
		for (Object ijo : inputjson.entrySet()) {
			if (!((Map.Entry) ijo).getKey().toString().equals("everyNodeList")
					&& !((Map.Entry) ijo).getKey().toString().equals("areaInfo")) {
				inParam.put(((Map.Entry) ijo).getKey().toString().replaceAll("\"", ""),
						((Map.Entry) ijo).getValue().toString().replaceAll("\"", ""));
			}
		}
		// 开始执行时间
		Date startDate = DateUtils.getNowDate();
		String startExecuateTime = DateUtils.formatDate(startDate, DateUtils.YYYY_MM_DD_HH_MM_SS);
		boolean result = true;
		int index = 0;
		JSONObject reJson = new JSONObject();
		JSONObject nextResult = new JSONObject();
		// 如果
		String ifString = ((JSONObject) resultArray1.get(3)).get("if").toString();
		ifString = StringEscapeUtils.unescapeXml(ifString);
		// 那么
		String successString = ((JSONObject) resultArray1.get(3)).get("success").toString();
		successString = StringEscapeUtils.unescapeXml(successString);
		// 遍历替换if中的变量
		Iterator<String> it = inputjson.keys();
		String ifStringOld = ifString;
		while (it.hasNext()) {
			// 获得key
			String key = it.next();
			ifString = ifString.replaceAll("'" + key + "'",
					NumericRegxUtils.isNumber(inputjson.getString(key)) ? inputjson.getString(key)
							: "'" + inputjson.getString(key) + "'");
			ifStringOld = ifStringOld.replaceAll("'" + key + "'",
					NumericRegxUtils.isNumber(inputjson.getString(key))
							? map.get(key) == null ? inputjson.getString(key) : map.get(key).toString()
							: "'" + inputjson.getString(key) + "'");
		}
		ifStringOld = ifStringOld.replaceAll("&&", "并且").replaceAll("\\|\\|", "或者");
		String[] ifStringOldList = ifStringOld.split("AND");
		String[] iflist = ifString.split("AND");
		String[] succlist = successString.split("AND");
		// 执行if判断
		ScriptEngineManager manager = new ScriptEngineManager();
		ScriptEngine se = manager.getEngineByName("js");
		for (int m = 0, iflistlength = iflist.length; m < iflistlength; m++) {
			try {
				result = (Boolean) se.eval(iflist[m]);
				if (result) {
					reason = reason.append("满足：").append(ifStringOldList[m]).append(",");
					String[] succlist1 = succlist[m].split("==");
					// 遍历替换success中的变量
					inputjson = sortJson(inputjson);

					// 执行自定义函数
					if (succlist1[1].contains("(") || succlist1[1].contains("+") || succlist1[1].contains("-")
							|| succlist1[1].contains("*") || succlist1[1].contains("/")) {
						String[] temp = succlist1[1].split("\\^");
						String tempStr = "";
						for (int i = 0; i < temp.length; i++) {
							if (temp[i].indexOf("com") != -1) {
								tempStr += temp[i];
							} else {
								Iterator<String> it1 = inputjson.keys();
								while (it1.hasNext()) {
									// 获得key
									String key = it1.next();
									// 特别注意数字不带单引号，字符串带单引号
									temp[i] = temp[i].replaceAll(key,
											NumericRegxUtils.isNumber(inputjson.getString(key))
													? inputjson.getString(key)
													: "'" + inputjson.getString(key) + "'");
								}
								tempStr += temp[i];
							}
						}
						try {
							String res = se.eval(tempStr.replaceAll("&@", "")).toString();
							// 赋值
							inputjson.put(succlist1[0], res);
						} catch (ScriptException e) {
							e.printStackTrace();
						}
					} else {
						Iterator<String> it1 = inputjson.keys();
						while (it1.hasNext()) {
							// 获得key
							String key = it1.next();
							// 特别注意数字不带单引号，字符串带单引号
							succlist1[1] = succlist1[1].replaceAll(key,
									NumericRegxUtils.isNumber(inputjson.getString(key)) ? inputjson.getString(key)
											: "'" + inputjson.getString(key) + "'");
						}
						// 赋值
						inputjson.put(succlist1[0], succlist1[1].replaceAll("&@", ""));
					}
					index = m;
				}
			} catch (ScriptException e) {
				e.printStackTrace();
			}
		}
		Map<Object, Object> outParam = new HashMap<>();
		for (Object ijo : inputjson.entrySet()) {
			if (!((Map.Entry) ijo).getKey().toString().equals("everyNodeList")
					&& !((Map.Entry) ijo).getKey().toString().equals("areaInfo")) {
				outParam.put(((Map.Entry) ijo).getKey().toString().replaceAll("\"", ""),
						((Map.Entry) ijo).getValue().toString().replaceAll("\"", ""));
			}
		}
		reJson = inputjson;
		if (resultArray1.get(2).equals("area")) {
			if (areaFirst.equals("")) {// 判断是否是循环的第一个 节点
				areaFirst = resultArray1.getString(0);
				reJson.put("areaFirst", areaFirst);
			}
		}
		nextResult = runNextNode(resultArray1, nodeArray, lineArray, inputjson, areaArray, areaFirst, ruleId, index,
				reason, map, startDate, inParam, outParam);
		if (!nextResult.toString().equals("{}")) {
			return nextResult;
		}
		// 结束执行时间
		Date endDate = DateUtils.getNowDate();
		String endExecuateTime = DateUtils.formatDate(endDate, DateUtils.YYYY_MM_DD_HH_MM_SS);
		reJson.put("startExecTime", startExecuateTime);
		reJson.put("endExecTime", endExecuateTime);
		reJson.put("execTotalTimeMills", "耗时: " + (endDate.getTime() - startDate.getTime()) + " 毫秒");
		reJson.put("execStatus", RuleConstants.NODE_EXEC_SUCCESS);
		return reJson;
	}

	@Override
	public void onEvent(AppBeanLoadEndEvent event) throws Throwable {
		NodeExecFactory.register(NodeExecEnums.MATR_NODE.getCode(), this);
	}
}
